#pragma once

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/noncopyable.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/system/error_code.hpp>

#include <iostream>
#include <string>

using namespace boost::asio;
using namespace std;

extern io_service g_service;

class CTalkToClient 
	: public boost::enable_shared_from_this<CTalkToClient>,
	boost::noncopyable
{
private:
	typedef boost::shared_ptr<CTalkToClient> ptr;
	CTalkToClient()
		:m_socketUdp(g_service, ip::udp::endpoint(ip::udp::v4(), 8001))
	{

	}
	static ptr m_talkToClient;

public:
	~CTalkToClient()
	{
		Stop();
	}

	static void New_()
	{
		m_talkToClient.reset(new CTalkToClient());
	}

	static void Start()
	{
		m_talkToClient->start();
	}

private:
	void start()
	{
		m_socketUdp.async_receive_from(buffer(m_recvMsg), m_epService, 
			boost::bind(
			&CTalkToClient::HandlerRecvFrom,
			shared_from_this(),
			_1,
			_2
			));
	}

	void HandlerRecvFrom(const boost::system::error_code &ec, int iBytes)
	{
		if(!ec)
		{
			m_strMsg = string(m_recvMsg, iBytes);
			m_socketUdp.async_send_to(buffer(m_strMsg), m_epService, boost::bind(
				&CTalkToClient::HandlerSendTo,
				shared_from_this(),
				_1,
				_2
				));
		}
		else
		{
			Stop();
		}
	}

	void HandlerSendTo(const boost::system::error_code &ec, int iBytes)
	{
		if(!ec)
		{
			if(iBytes > 0)
			{
				cout << "Send data : " << m_strMsg << endl;
				start();				
			}
		}
		else
		{
			Stop();
		}
	}

	void Stop()
	{
		m_socketUdp.close();
	}

private:
	ip::udp::socket m_socketUdp;
	ip::udp::endpoint m_epService;

	char m_recvMsg[1024];
	string m_strMsg;
};

__declspec(selectany) CTalkToClient::ptr CTalkToClient::m_talkToClient;
